'use strict';

class _Test {
  title = '这是首页';
  constructor() {
    console.log('这是测试类');
    this.title = '这是测试类';
  }
  func() {
    console.log(this.title);
  }
  getTitle() {
    return this.title;
  }
}

const _test = new _Test('这是测试类');
for (const key in _test) {
  // 遍历实例属性
  console.log(key);
}

function Test(title) {
  console.log('这是测试函数');
  if (new.target === undefined) {
    throw new Error('构造函数只通过new调用函数');
  }
  this.title = title;
}

// --重写Test的原型方法func，只能通过实例调用，不能通过new调用
Object.defineProperty(Test.prototype, 'func', {
  value: function () {
    if (new.target) {
      throw new Error('方法只不能通过new调用函数');
    }
    console.log(this.title);
  },
  enumerable: false,
  configurable: true,
});
Object.defineProperty(Test.prototype, 'getTitle', {
  value: function () {
    if (new.target) {
      throw new Error('方法只不能通过new调用函数');
    }
    return this.title;
  },
  enumerable: false,
  configurable: true,
});
// Test.prototype.func = function () {
//   console.log(this.title);
// };
// Test.prototype.getTitle = function () {
//   return this.title;
// };
// Test("测试函数"); // 错误示例
const test = new Test('这是测试函数');

for (const key in test) {
  // 遍历实例属性
  console.log(key);
}
test.func();

// new Test.prototype.func();

// 默认配置项
function foo(options = {}) {
  const defaultOptions = {
    name: '张三',
    age: 18,
  };
  const mergedOptions = {
    ...defaultOptions,
    ...options,
  };
  console.log(mergedOptions);
  return mergedOptions;
}
foo({ name: 'Hehe', age: 35 }); // { name: '张三', age: 18 }


// 函数代理模式，在不改变原函数的情况下，添加一些额外的功能
const calculator = {
  title: '计算器',
  count: 0,
  next() {
    console.log('next', this.count);
    return ++this.count;
  },
  double(a) {
    console.log('double', a * 2);
  },
  add(a, b) {
    return a + b;
  },
};

for (const key in calculator) {
  if (typeof calculator[key] === 'function') {
    console.log(calculator[key].name);
    const orginal = calculator[key];
    calculator[key] = (...args) => {
      console.log('打印开始日志', key);
      const result = orginal.call(calculator, ...args);
      console.log('打印结束日志', key);
      return result;
    };
  }
}

calculator.next();
calculator.double(5);


// this指向问题
window.title = '这是全局变量';
const obj = {
  name: '张三',
  age: 18,
  getName() {
    console.log(this.name);
    console.log(this.title);
  },
  get: () => {
    console.log(this.name);
    console.log(this.title);
  },
  getAge() {
    console.log(this);
    (() => {
      console.log(this.age);
    })();
  },
};

obj.getName();
obj.get();
obj.getAge();


// 函数柯里化
function currying(fn,...args){
  return function fun(...args){
    if(args.length>=fn.length){
      return fn.call(this, ...args);
    }
    else{
      return function (...args2){
        return fun.call(this, ...args2, ...args);
      };
    }
  };
}

const add=(a,b,c,d)=>a+b+c+d;

const curryingAdd=currying(add);
console.log(curryingAdd(1)(2)(3)(4));